<template>
  <a-drawer
    title="新建课程"
    :open="open"
    :maskClosable="false"
    width="634"
    @close="onCancel"
    :footer="footer"
  >
    <div v-if="init" class="float-left text-center mt-30">
      <a-spin></a-spin>
    </div>
    
    <div v-else class="float-left mt-24">
      <!-- 资源选择弹窗 -->
      <SelectResource
        :defaultKeys="formState.hasChapter === 0 ? hours : changeChapterHours(chapterHours)"
        :open="videoVisible"
        @cancel="setVideoVisible(false)"
        @selected="handleResourceSelected"
      />
      
      <SelectAttachment
        :defaultKeys="attachments"
        :open="attachmentVisible"
        @cancel="setAttachmentVisible(false)"
        @selected="selectAttachmentData"
      />
      
      <SelectRange
        :defaultDepIds="depIds"
        :defaultDeps="deps"
        :open="idsVisible"
        @cancel="setIdsVisible(false)"
        @selected="handleRangeSelected"
      />
      
      <a-form
        ref="formRef"
        :model="formState"
        :label-col="{ span: 5 }"
        :wrapper-col="{ span: 19 }"
        @finish="onFinish"
        @finishFailed="onFinishFailed"
      >
        <!-- 课程分类 -->
        <a-form-item
          label="课程分类"
          name="category_ids"
          :rules="[{ required: true, message: '请选择课程分类!' }]"
        >
          <a-tree-select
            v-model:value="formState.category_ids"
            show-checked-strategy="SHOW_ALL"
            allow-clear
            multiple
            style="width: 424px"
            :tree-data="categories"
            placeholder="请选择课程分类"
            tree-default-expand-all
          />
        </a-form-item>

        <!-- 课程名称 -->
        <a-form-item
          label="课程名称"
          name="title"
          :rules="[{ required: true, message: '请在此处输入课程名称!' }]"
        >
          <a-input
            v-model:value="formState.title"
            style="width: 424px"
            placeholder="请在此处输入课程名称"
            allow-clear
          />
        </a-form-item>

        <!-- 课程属性 -->
        <a-form-item
          label="课程属性"
          name="isRequired"
          :rules="[{ required: true, message: '请选择课程属性!' }]"
        >
          <a-radio-group v-model:value="formState.isRequired">
            <a-radio :value="1">必修课</a-radio>
            <a-radio :value="0" style="margin-left: 22px">选修课</a-radio>
          </a-radio-group>
        </a-form-item>

        <!-- 指派部门 -->
        <a-form-item
          label="指派部门"
          name="type"
          :rules="[{ required: true, message: '请选择指派部门!' }]"
        >
          <a-radio-group v-model:value="formState.type" @change="getType">
            <a-radio value="open">全部部门</a-radio>
            <a-radio value="elective">选择部门</a-radio>
          </a-radio-group>
        </a-form-item>

        <!-- 选择部门 -->
        <a-form-item
          v-if="formState.type === 'elective'"
          label="选择部门"
          name="ids"
          :rules="[{ required: true, message: '请选择部门!' }]"
        >
          <div class="d-flex" style="width: 100%; flex-wrap: wrap; margin-bottom: -8px">
            <a-button type="default" style="margin-bottom: 14px" @click="setIdsVisible(true)">
              添加范围
            </a-button>
            <div class="d-flex" style="width: 100%; flex-wrap: wrap; margin-bottom: -16px">
              <a-tag
                v-for="(item, i) in deps"
                :key="i"
                closable
                :style="{
                  height: '32px',
                  lineHeight: '32px',
                  fontSize: '14px',
                  color: '#FF4D4F',
                  background: 'rgba(255,77,79,0.1)',
                  marginRight: '16px',
                  marginBottom: '16px',
                }"
                @close="(e) => handleTagClose(e, i)"
              >
                {{ item.title }}
              </a-tag>
            </div>
          </div>
        </a-form-item>

        <!-- 课程封面 -->
        <a-form-item
          label="课程封面"
          name="thumb"
          :rules="[{ required: true, message: '请上传课程封面!' }]"
        >
          <div class="d-flex">
            <a-image
              :src="thumb"
              :width="160"
              :height="120"
              :style="{ borderRadius: '6px' }"
              :preview="false"
            />
            <div class="c-flex ml-8 flex-1">
              <div class="d-flex mb-28">
                <div
                  v-for="(defaultThumb, index) in defaultThumbs"
                  :key="index"
                  :class="['thumb-item', { 'thumb-item-active': thumb === defaultThumb }]"
                  @click="handleThumbClick(defaultThumb, index)"
                >
                  <a-image
                    :src="defaultThumb"
                    :width="80"
                    :height="60"
                    :style="{ borderRadius: '6px' }"
                    :preview="false"
                  />
                </div>
              </div>
              <div class="d-flex">
                <UploadImageButton
                  text="更换封面"
                  @selected="handleImageSelected"
                />
                <span class="helper-text ml-8">（推荐尺寸:400x300px）</span>
              </div>
            </div>
          </div>
        </a-form-item>

        <!-- 课时列表 -->
        <a-form-item
          label="课时列表"
          name="hasChapter"
          :rules="[{ required: true, message: '请选择课时列表!' }]"
        >
          <a-radio-group v-model:value="formState.hasChapter" @change="getChapterType">
            <a-radio :value="0">无章节</a-radio>
            <a-radio :value="1" style="margin-left: 22px">有章节</a-radio>
          </a-radio-group>
        </a-form-item>

        <!-- 无章节模式 -->
        <div v-if="formState.hasChapter === 0" class="c-flex mb-24">
          <a-form-item>
            <div class="ml-120">
              <a-button type="primary" @click="setVideoVisible(true)">
                添加课时
              </a-button>
            </div>
          </a-form-item>
          <div class="hous-box">
            <span v-if="treeData.length === 0" class="no-hours">
              请点击上方按钮添加课时
            </span>
            <TreeHours
              v-else
              :data="treeData"
              @remove-item="delHour"
              @update="transHour"
            />
          </div>
        </div>

        <!-- 有章节模式 -->
        <div v-if="formState.hasChapter === 1" class="c-flex mb-24">
          <div
            v-for="(item, index) in chapters"
            :key="`chapter-${index}`"
            class="chapter-item"
          >
            <div class="d-flex">
              <div class="chapter-label">章节{{ index + 1 }}：</div>
              <a-input
                :value="item.name"
                class="chapter-input"
                @change="(e) => setChapterName(index, e.target.value)"
                allow-clear
                placeholder="请在此处输入章节名称"
              />
              <a-button class="mr-16" type="primary" @click="handleAddVideo(index)">
                添加课时
              </a-button>
              <a-button @click="delChapter(index)">删除章节</a-button>
            </div>
            <div class="chapter-hous-box">
              <span v-if="item.hours.length === 0" class="no-hours">
                请点击上方按钮添加课时
              </span>
              <TreeHours
                v-else
                :data="item.hours"
                @remove-item="(id) => delChapterHour(index, id)"
                @update="(arr) => transChapterHour(index, arr)"
              />
            </div>
          </div>
          <a-form-item>
            <div class="ml-120">
              <a-button @click="addNewChapter">添加章节</a-button>
            </div>
          </a-form-item>
        </div>

        <!-- 更多选项 -->
        <a-form-item label="更多选项">
          <div
            :class="['drop-item', { active: showDrop }]"
            @click="setShowDrop(!showDrop)"
          >
            <i class="iconfont icon-icon-xiala c-red" style="font-size: 14px" />
            <span>(课程简介、课件)</span>
          </div>
        </a-form-item>

        <!-- 展开内容 -->
        <div v-if="showDrop" class="c-flex">
          <a-form-item label="课程简介" name="short_desc">
            <a-textarea
              v-model:value="formState.short_desc"
              style="width: 424px; min-height: 80px"
              allow-clear
              placeholder="请输入课程简介（最多200字）"
              :maxlength="200"
            />
          </a-form-item>
          <a-form-item label="课程附件">
            <a-button type="primary" @click="setAttachmentVisible(true)">
              添加课件
            </a-button>
          </a-form-item>
          <div class="hous-box">
            <span v-if="attachmentData.length === 0" class="no-hours">
              请点击上方按钮添加课件
            </span>
            <TreeAttachments
              v-else
              :data="attachmentData"
              @remove-item="delAttachments"
              @update="transAttachments"
            />
          </div>
        </div>
      </a-form>
    </div>
  </a-drawer>
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed, h } from 'vue';
import { 
  Drawer as ADrawer, 
  Form as AForm, 
  Input as AInput, 
  Radio as ARadio, 
  Button as AButton, 
  Image as AImage, 
  Spin as ASpin, 
  Tag as ATag, 
  TreeSelect as ATreeSelect,
  Textarea as ATextarea,
  Modal,
  message,
  Space
} from 'ant-design-vue';
import { ExclamationCircleFilled } from '@ant-design/icons-vue';
import { course, department } from '@/api';
import UploadImageButton from '@/components/Common/upload-image-button.vue'
import SelectResource from '@/components/Common/select-resource.vue'
import SelectAttachment from '@/components/Common/select-attachment.vue'
import SelectRange from '@/components/Common/select-range.vue'
import TreeHours from './hours.vue';
import TreeAttachments from './attachments.vue';
import defaultThumb1 from '@/assets/thumb/thumb1.png';
import defaultThumb2 from '@/assets/thumb/thumb2.png';
import defaultThumb3 from '@/assets/thumb/thumb3.png';

interface Props {
  cateIds: any[];
  open: boolean;
  onCancel: () => void;
}

interface Option {
  value: string | number;
  title: string;
  children?: Option[];
}

interface Chapter {
  name: string;
  hours: any[];
}

const props = defineProps<Props>();

const formRef = ref();
const loading = ref(false);
const init = ref(true);
const departments = ref<Option[]>([]);
const categories = ref<Option[]>([]);
const thumb = ref(defaultThumb1);
const defaultThumbs = [defaultThumb1, defaultThumb2, defaultThumb3];
const formState = reactive({
  title: '',
  thumb: -1,
  isRequired: 1,
  short_desc: '',
  hasChapter: 0,
  category_ids: [] as any[],
  type: 'open',
  ids: [] as number[],
});
const chapters = ref<Chapter[]>([]);
const hours = ref<number[]>([]);
const chapterHours = ref<any[]>([]);
const treeData = ref<any[]>([]);
const videoVisible = ref(false);
const addvideoCurrent = ref(0);
const showDrop = ref(false);
const attachmentVisible = ref(false);
const attachmentData = ref<any[]>([]);
const attachments = ref<number[]>([]);
const depIds = ref<number[]>([]);
const deps = ref<any[]>([]);
const idsVisible = ref(false);

const handleConfirm = async () => {
  if (!formRef.value) return;
  try {
    const values = await formRef.value.validate();
    onFinish(values);
  } catch (err) {
    console.log('表单校验失败', err);
  }
};
const footer = computed(() =>
  h(Space, { class: 'j-r-flex' }, [
    h(AButton, { onClick: props.onCancel }, '取 消'),
    h(AButton, { 
      loading: loading.value, 
      onClick: handleConfirm, 
      type: 'primary' 
    }, '确 认')
  ])
);

// Watchers
watch(() => props.open, (newVal) => {
  if (newVal) {
    initData();
  }
});

watch(() => props.cateIds, () => {
  if (props.open) {
    initData();
  }
});

// Methods
const initData = async () => {
  init.value = true;
  await getParams();
  await getCategory();
  init.value = false;
};

const getParams = async () => {
  try {
    const res: any = await department.departmentList({});
    const departmentsData = res.data.departments;
    const departCount = res.data.dep_user_count;
    
    if (JSON.stringify(departmentsData) !== '{}') {
      const new_arr = checkArr(departmentsData, 0, departCount);
      departments.value = new_arr;
    }
    
    formState.type = 'open';
    formState.ids = [];
  } catch (error) {
    console.error('获取部门数据失败:', error);
  }
};

const getCategory = async () => {
  try {
    const res: any = await course.createCourse();
    const categoriesData = res.data.categories;
    
    if (JSON.stringify(categoriesData) !== '{}') {
      const new_arr = checkArr(categoriesData, 0, null);
      categories.value = new_arr;
    }

    if (props.cateIds.length !== 0 && props.cateIds[0] !== 0) {
      const item = checkChild(res.data.categories, props.cateIds[0]);
      const arr: any[] = [];
      
      if (item === undefined) {
        arr.push(props.cateIds[0]);
      } else if (item.parent_chain === '') {
        arr.push(props.cateIds[0]);
      } else {
        const new_arr = item.parent_chain.split(',');
        new_arr.forEach((num: any) => {
          arr.push(Number(num));
        });
        arr.push(props.cateIds[0]);
      }
      formState.category_ids = arr;
    } else {
      formState.category_ids = props.cateIds;
    }
  } catch (error) {
    console.error('获取分类数据失败:', error);
  }
};

const checkChild = (departments: any[], id: number) => {
  for (const key in departments) {
    for (let i = 0; i < departments[key].length; i++) {
      if (departments[key][i].id === id) {
        return departments[key][i];
      }
    }
  }
  return undefined;
};

const getNewTitle = (title: any, id: number, counts: any) => {
  if (counts) {
    const value = counts[id] || 0;
    return `${title}(${value})`;
  }
  return title;
};

const checkArr = (departments: any[], id: number, counts: any) => {
  const arr = [];
  if (!departments[id]) return arr;
  
  for (let i = 0; i < departments[id].length; i++) {
    if (!departments[departments[id][i].id]) {
      arr.push({
        title: getNewTitle(departments[id][i].name, departments[id][i].id, counts),
        value: departments[id][i].id,
      });
    } else {
      const new_arr = checkArr(departments, departments[id][i].id, counts);
      arr.push({
        title: getNewTitle(departments[id][i].name, departments[id][i].id, counts),
        value: departments[id][i].id,
        children: new_arr,
      });
    }
  }
  return arr;
};

const onFinish = async (values: any) => {
  if (loading.value) return;
  
  let dep_ids: any[] = [];
  if (formState.type === 'elective') {
    dep_ids = depIds.value;
  }
  
  if (chapters.value.length === 0 && treeData.value.length === 0) {
    message.error('请配置课时');
    return;
  }
  
  loading.value = true;
  try {
    await course.storeCourse(
      values.title,
      values.thumb,
      values.short_desc,
      1,
      values.isRequired,
      dep_ids,
      values.category_ids,
      chapters.value,
      treeData.value,
      attachmentData.value
    );
    message.success('保存成功！');
    props.onCancel();
  } catch (error) {
    console.error('保存课程失败:', error);
  } finally {
    loading.value = false;
  }
};

const onFinishFailed = (errorInfo: any) => {
  console.log('Failed:', errorInfo);
};

const getType = (e: any) => {
  formState.type = e.target.value;
};

const handleResourceSelected = (arr: any, videos: any) => {
  if (arr.length === 0) {
    message.error('请选择视频');
    return;
  }
  
  if (formState.hasChapter === 0) {
    selectData(arr, videos);
  } else {
    selectChapterData(arr, videos);
  }
};

const selectData = (arr: any, videos: any) => {
  hours.value = [...hours.value, ...arr];
  treeData.value = [...treeData.value, ...videos];
  videoVisible.value = false;
};

const selectChapterData = (arr: any, videos: any) => {
  const data = [...chapters.value];
  const keys = [...chapterHours.value];
  keys[addvideoCurrent.value] = keys[addvideoCurrent.value].concat(arr);
  data[addvideoCurrent.value].hours = data[addvideoCurrent.value].hours.concat(videos);
  chapters.value = data;
  chapterHours.value = keys;
  videoVisible.value = false;
};

const selectAttachmentData = (arr: any, videos: any) => {
  if (arr.length === 0) {
    message.error('请选择课件');
    return;
  }
  attachments.value = [...attachments.value, ...arr];
  attachmentData.value = [...attachmentData.value, ...videos];
  attachmentVisible.value = false;
};

const getChapterType = (e: any) => {
  const newType = e.target.value;
  
  if (chapters.value.length > 0) {
    Modal.confirm({
      title: '操作确认',
      icon: h(ExclamationCircleFilled),
      content: '切换列表选项会清空已添加课时，确认切换？',
      centered: true,
      okText: '确认',
      cancelText: '取消',
      onOk() {
        formState.hasChapter = newType;
        resetChapterData();
      },
      onCancel() {
        // 保持原值
      },
    });
  } else {
    formState.hasChapter = newType;
    resetChapterData();
  }
};

const resetChapterData = () => {
  chapters.value = [];
  hours.value = [];
  chapterHours.value = [];
  treeData.value = [];
};

const delHour = (id: number) => {
  const data = treeData.value.filter(item => item.rid !== id);
  treeData.value = data;
  hours.value = data.map(item => item.rid);
};

const transHour = (arr: any[]) => {
  hours.value = arr;
  const newData = treeData.value.filter(item => arr.includes(item.rid));
  treeData.value = newData;
};

const delAttachments = (id: number) => {
  const data = attachmentData.value.filter(item => item.rid !== id);
  attachmentData.value = data;
  attachments.value = data.map(item => item.rid);
};

const transAttachments = (arr: any[]) => {
  attachments.value = arr;
  const newData = attachmentData.value.filter(item => arr.includes(item.rid));
  attachmentData.value = newData;
};

const addNewChapter = () => {
  chapters.value.push({
    name: '',
    hours: [],
  });
  chapterHours.value.push([]);
};

const setChapterName = (index: number, value: string) => {
  const arr = [...chapters.value];
  arr[index].name = value;
  chapters.value = arr;
};

const delChapter = (index: number) => {
  Modal.confirm({
    title: '操作确认',
    icon: h(ExclamationCircleFilled),
    content: '删除章节会清空已添加课时，确认删除？',
    centered: true,
    okText: '确认',
    cancelText: '取消',
    onOk() {
      chapters.value.splice(index, 1);
      chapterHours.value.splice(index, 1);
    },
  });
};

const delChapterHour = (index: number, id: number) => {
  const chapter = chapters.value[index];
  chapter.hours = chapter.hours.filter(item => item.rid !== id);
  chapterHours.value[index] = chapter.hours.map(item => item.rid);
};

const transChapterHour = (index: number, arr: any[]) => {
  chapterHours.value[index] = arr;
  const chapter = chapters.value[index];
  chapter.hours = chapter.hours.filter(item => arr.includes(item.rid));
};

const changeChapterHours = (arr: any[]) => {
  return arr.flat();
};

const handleThumbClick = (selectedThumb: string, index: number) => {
  thumb.value = selectedThumb;
  formState.thumb = -(index + 1);
};

const handleImageSelected = (url: string, id: number) => {
  thumb.value = url;
  formState.thumb = id;
};

const handleAddVideo = (index: number) => {
  addvideoCurrent.value = index;
  videoVisible.value = true;
};

const handleRangeSelected = (selDepIds: number[], selDeps: any[]) => {
  depIds.value = selDepIds;
  deps.value = selDeps;
  formState.ids = selDepIds;
  idsVisible.value = false;
};

const handleTagClose = (e: Event, index: number) => {
  e.preventDefault();
  deps.value.splice(index, 1);
  depIds.value.splice(index, 1);
  formState.ids = [...depIds.value];
};

// Setters
const setVideoVisible = (visible: boolean) => {
  videoVisible.value = visible;
};

const setAttachmentVisible = (visible: boolean) => {
  attachmentVisible.value = visible;
};

const setIdsVisible = (visible: boolean) => {
  idsVisible.value = visible;
};

const setShowDrop = (visible: boolean) => {
  showDrop.value = visible;
};
</script>

<style scoped>
.d-flex {
  display: flex;
}

.c-flex {
  display: flex;
  flex-direction: column;
}

.ml-8 {
  margin-left: 8px;
}

.ml-120 {
  margin-left: 120px;
}

.mr-16 {
  margin-right: 16px;
}

.mb-24 {
  margin-bottom: 24px;
}

.mb-28 {
  margin-bottom: 28px;
}

.mt-24 {
  margin-top: 24px;
}

.mt-30 {
  margin-top: 30px;
}

.flex-1 {
  flex: 1;
}

.float-left {
  float: left;
}

.text-center {
  text-align: center;
}

.helper-text {
  color: #999;
  font-size: 12px;
}

.c-red {
  color: #ff4d4f;
}

.j-r-flex {
  display: flex;
  justify-content: flex-end;
}

.thumb-item {
  padding: 4px;
  border: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  margin-right: 8px;
}

.thumb-item-active {
  border-color: #1890ff;
}

.hous-box, .chapter-hous-box {
  min-height: 100px;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  padding: 16px;
  margin-top: 16px;
}

.no-hours {
  color: #999;
  font-size: 14px;
}

.chapter-item {
  margin-bottom: 24px;
  padding: 16px;
  border: 1px solid #f0f0f0;
  border-radius: 6px;
}

.chapter-label {
  width: 80px;
  line-height: 32px;
  font-weight: 500;
}

.chapter-input {
  width: 200px;
  margin-right: 16px;
}

.drop-item {
  cursor: pointer;
  color: #1890ff;
}

.drop-item.active {
  color: #ff4d4f;
}
</style>